package com.yao.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yao.system.entity.*;
import com.yao.system.entity.dto.UserDTO;
import com.yao.system.entity.vo.InterviewVO;
import com.yao.system.mapper.InterviewMapper;
import com.yao.system.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yao.system.util.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 霖
 * @since 2024-04-15
 */
@Service
@RequiredArgsConstructor
public class InterviewServiceImpl extends ServiceImpl<InterviewMapper, Interview> implements IInterviewService {

    private final ICompanyService companyService;
    private final IJobService jobService;
    private final IUserService userService;
    private final IResumeService resumeService;
    private final ThreadPoolExecutor coreThreadPool;

    @Override
    public Result addInterview(Interview interview) {
        if (interview == null) {
            throw new RuntimeException("新增失败");
        }
        Interview exist = lambdaQuery()
                .eq(Interview::getJobId, interview.getJobId())
                .eq(Interview::getUserId, interview.getUserId())
                .one();
        if (exist != null) {
            //throw new RuntimeException("已向该用户发送过该岗位的面试邀请");
            return Result.error("已向该用户发送过该岗位的面试邀请");
        }
        UserDTO user = UserContext.getUser();
        Company company = companyService.lambdaQuery()
                .eq(Company::getUserId, user.getId())
                .one();
        //Resume resume = resumeService.lambdaQuery()
        //        .eq(Resume::getUserId, interview.getUserId())
        //        .one();
        interview.setCompanyId(company.getId());
        //interview.setCompanyPhone(company.getPhone());
        interview.setCompanyUserId(user.getId());
        //interview.setUserPhone(resume.getPhone());
        save(interview);
        return Result.ok("邀请成功");
    }

    @Override
    public Result getInterviewList(Integer page, Integer size) {
        Page<Interview> pageData = lambdaQuery()
                .eq(Interview::getCompanyUserId, UserContext.getUser().getId())
                .page(Page.of(page, size));
        List<Interview> interviewList = pageData.getRecords();
        int total = (int) pageData.getTotal();//这里强转为int 是因为会把long序列化为string
        int pages = (int) pageData.getPages();//前端的这些页数相关的数据需要数字类型 string会显示不出来
        //没有记录 直接返回空数据
        if (interviewList.isEmpty()) {
            Map<String, Object> map = new HashMap<>();
            map.put("record", null);
            map.put("total", total);
            map.put("pages", pages);
            return Result.ok(map);
        }

        Set<Long> userIds = new HashSet<>();
        Set<Long> jobIds = new HashSet<>();
        for (Interview interview : interviewList) {
            userIds.add(interview.getUserId());
            jobIds.add(interview.getJobId());
        }

        //多线程加快查询
        CompletableFuture<Map<Long, User>> userFuture = CompletableFuture.supplyAsync(() -> {
            return userService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Resume>> resumeFuture = CompletableFuture.supplyAsync(() -> {
            return resumeService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Job>> companyFuture = CompletableFuture.supplyAsync(() -> {
            return jobService.getByIds(jobIds);
        }, coreThreadPool);

        Company company = companyService.lambdaQuery()
                .eq(Company::getUserId, UserContext.getUser().getId())
                .one();

        Map<Long, User> userMap = userFuture.join();
        Map<Long, Job> jobMap = companyFuture.join();
        Map<Long, Resume> resumeMap = resumeFuture.join();

        List<InterviewVO> list = new ArrayList<>();
        for (Interview interview : interviewList) {
            InterviewVO vo = new InterviewVO();
            User user = userMap.get(interview.getUserId());
            Job job = jobMap.get(interview.getJobId());
            Resume resume = resumeMap.get(interview.getUserId());

            BeanUtil.copyProperties(interview, vo);
            if (job != null) {
                vo.setCompanyName(job.getCompany());
                vo.setAddress(job.getAddress());
                vo.setTitle(job.getTitle());
            }
            vo.setUsername(user.getName());
            vo.setImage(user.getImage());
            vo.setUserPhone(resume.getPhone());
            vo.setCompanyPhone(company.getPhone());
            vo.setEmail(company.getEmail());
            if (job == null)
                vo.setStatus(2);
            list.add(vo);
        }
        return Result.ok(PageResult.of(total, pages, list));
    }

    @Override
    public Result updateInterviewStatus(Long id, Integer status) {
        Interview interview = new Interview();
        interview.setId(id);
        interview.setStatus(status);
        updateById(interview);
        return Result.ok("修改成功");
    }

    /**
     * 查询 普通用户收到的面试邀请列表
     */
    @Override
    public Result getUserInterviewList(Integer page, Integer size) {
        Page<Interview> pageData = lambdaQuery()
                .eq(Interview::getUserId, UserContext.getUser().getId())
                .page(Page.of(page, size));

        List<Interview> interviewList = pageData.getRecords();
        int total = (int) pageData.getTotal();//这里强转为int 是因为会把long序列化为string
        int pages = (int) pageData.getPages();//前端的这些页数相关的数据需要数字类型 string会显示不出来
        //没有记录 直接返回空数据
        if (interviewList.isEmpty()) {
            return Result.ok(PageResult.of(total, pages, null));
        }

        Set<Long> userIds = new HashSet<>();
        Set<Long> jobIds = new HashSet<>();
        Set<Long> companyIds = new HashSet<>();
        for (Interview interview : interviewList) {
            userIds.add(interview.getUserId());
            jobIds.add(interview.getJobId());
            companyIds.add(interview.getCompanyId());
        }

        //多线程加快查询
        CompletableFuture<Map<Long, User>> userFuture = CompletableFuture.supplyAsync(() -> {
            return userService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Resume>> resumeFuture = CompletableFuture.supplyAsync(() -> {
            return resumeService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Job>> jobFuture = CompletableFuture.supplyAsync(() -> {
            return jobService.getByIds(jobIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Company>> companyFuture = CompletableFuture.supplyAsync(() -> {
            return companyService.getByIds(companyIds);
        });

        //Company company = companyService.lambdaQuery()
        //        .eq(Company::getUserId, UserContext.getUser().getId())
        //        .one();

        Map<Long, User> userMap = userFuture.join();
        Map<Long, Job> jobMap = jobFuture.join();
        Map<Long, Resume> resumeMap = resumeFuture.join();
        Map<Long, Company> companyMap = companyFuture.join();

        List<InterviewVO> list = new ArrayList<>();
        for (Interview interview : interviewList) {
            InterviewVO vo = new InterviewVO();
            User user = userMap.get(interview.getUserId());
            Job job = jobMap.get(interview.getJobId());
            Resume resume = resumeMap.get(interview.getUserId());
            Company company = companyMap.get(interview.getCompanyId());

            BeanUtil.copyProperties(interview, vo);
            if (job != null) {
                vo.setCompanyName(job.getCompany());
                vo.setAddress(job.getAddress());
                vo.setTitle(job.getTitle());
            }
            vo.setUsername(user.getName());
            vo.setImage(user.getImage());
            vo.setUserPhone(resume.getPhone());
            vo.setCompanyPhone(company.getPhone());
            vo.setEmail(company.getEmail());
            list.add(vo);
        }
        return Result.ok(PageResult.of(total, pages, list));
    }

    @Override
    public Result queryInterviewList(Integer page, Integer size) {
        Page<Interview> pageData = lambdaQuery()
                .page(Page.of(page, size));

        List<Interview> interviewList = pageData.getRecords();
        int total = (int) pageData.getTotal();//这里强转为int 是因为会把long序列化为string
        int pages = (int) pageData.getPages();//前端的这些页数相关的数据需要数字类型 string会显示不出来
        //没有记录 直接返回空数据
        if (interviewList.isEmpty()) {
            Map<String, Object> map = new HashMap<>();
            map.put("record", null);
            map.put("total", total);
            map.put("pages", pages);
            return Result.ok(map);
        }

        Set<Long> userIds = new HashSet<>();
        Set<Long> jobIds = new HashSet<>();
        for (Interview interview : interviewList) {
            userIds.add(interview.getUserId());
            jobIds.add(interview.getJobId());
        }

        //多线程加快查询
        CompletableFuture<Map<Long, User>> userFuture = CompletableFuture.supplyAsync(() -> {
            return userService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Resume>> resumeFuture = CompletableFuture.supplyAsync(() -> {
            return resumeService.getByIds(userIds);
        }, coreThreadPool);
        CompletableFuture<Map<Long, Job>> companyFuture = CompletableFuture.supplyAsync(() -> {
            return jobService.getByIds(jobIds);
        }, coreThreadPool);

        Company company = companyService.lambdaQuery()
                .eq(Company::getUserId, UserContext.getUser().getId())
                .one();

        Map<Long, User> userMap = userFuture.join();
        Map<Long, Job> jobMap = companyFuture.join();
        Map<Long, Resume> resumeMap = resumeFuture.join();

        List<InterviewVO> list = new ArrayList<>();
        for (Interview interview : interviewList) {
            InterviewVO vo = new InterviewVO();
            User user = userMap.get(interview.getUserId());
            Job job = jobMap.get(interview.getJobId());
            Resume resume = resumeMap.get(interview.getUserId());

            BeanUtil.copyProperties(interview, vo);
            if (job != null) {
                vo.setCompanyName(job.getCompany());
                vo.setAddress(job.getAddress());
                vo.setTitle(job.getTitle());
            }
            vo.setUsername(user.getName());
            vo.setImage(user.getImage());
            vo.setUserPhone(resume.getPhone());
            if (company != null) {
                vo.setCompanyPhone(company.getPhone());
                vo.setEmail(company.getEmail());
            }
            if (job == null)
                vo.setStatus(2);
            list.add(vo);
        }
        return Result.ok(PageResult.of(total, pages, list));
    }
}
